package glazedlists.examples;

import ca.odell.glazedlists.BasicEventList;
import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.FilterList;
import ca.odell.glazedlists.GlazedLists;
import ca.odell.glazedlists.gui.TableFormat;
import ca.odell.glazedlists.matchers.AbstractMatcherEditor;
import ca.odell.glazedlists.matchers.Matcher;
import ca.odell.glazedlists.swing.EventTableModel;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class CustomMatcherEditorExample {

    public static class AmericanIdol {
        private String name;
        private int votes;
        private String nationality;

        public AmericanIdol(String name, int votes, String nationality) {
            this.name = name;
            this.votes = votes;
            this.nationality = nationality;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getNationality() {
            return nationality;
        }

        public void setNationality(String nationality) {
            this.nationality = nationality;
        }

        public int getVotes() {
            return votes;
        }

        public void setVotes(int votes) {
            this.votes = votes;
        }

        public void incrementVotes() {
            this.votes++;
        }
    }

    public static void main(String[] args) throws Exception {
        EventList<AmericanIdol> idols = GlazedLists.threadSafeList(new BasicEventList<>());
        idols.add(new AmericanIdol("Simon Cowell", 0, "British"));
        idols.add(new AmericanIdol("Paula Abdul", 0, "American"));
        idols.add(new AmericanIdol("Randy Jackson", 0, "American"));
        idols.add(new AmericanIdol("Ryan Seacrest", 0, "American"));

        final NationalityMatchEditor nationalityMatchEditor = new NationalityMatchEditor();
        final FilterList filterIdols = new FilterList(idols, nationalityMatchEditor);

        // build a Table
        String[] propertyNames = {"name", "votes"};
        String[] columnLabels = {"Name", "Votes"};
        TableFormat<AmericanIdol> tf = GlazedLists.tableFormat(AmericanIdol.class, propertyNames, columnLabels);
        JTable table = new JTable(new EventTableModel<>(filterIdols, tf));

        JFrame frame = new JFrame();
        frame.setLayout(new BorderLayout());
        frame.add(nationalityMatchEditor.getComponent(), BorderLayout.NORTH);
        frame.add(new JScrollPane(table));
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    private static class NationalityMatchEditor extends AbstractMatcherEditor implements ActionListener {
        private JComboBox nationalityChooser;

        public NationalityMatchEditor() {
            this.nationalityChooser = new JComboBox(new Object[] {"", "British", "American"});
            this.nationalityChooser.getModel().setSelectedItem("Filter by Nationality...");
            this.nationalityChooser.addActionListener(this);
        }

        public Component getComponent() {
            return nationalityChooser;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            final String nationality = (String) this.nationalityChooser.getSelectedItem();
            if (nationality == null || nationality.isEmpty()) {
                this.fireMatchAll();
            } else {
                this.fireChanged(new NationalityMatcher(nationality));
            }
        }

        private static class NationalityMatcher implements Matcher {
            private final String nationality;

            public NationalityMatcher(String nationality) {
                this.nationality = nationality;
            }

            @Override
            public boolean matches(Object item) {
                final AmericanIdol idol = (AmericanIdol) item;
                return this.nationality.equals(idol.getNationality());
            }
        }
    }
}
